import math
import importlib
from typing import Iterable
import numpy as np
import pandas as pd

import plotly.offline as py
pyplt = py.offline.plot
import plotly.graph_objs as go

from plotly.subplots import make_subplots
from plotly.figure_factory import create_distplot
import plotly.figure_factory as ff

class BaseGraph:
    def __init__(
            self, df: pd.DataFrame = None, layout: dict = {}, graph_kwargs: dict = None, col='',name='',
            **kwargs
    ):
        self._layout = layout
        self._df = df
        self._col = col
        self._name = name
        self._graph_kwargs = graph_kwargs

    def get_graph(self, graph_type):
        _graph_module = importlib.import_module("plotly.graph_objs")
        _graph_class = getattr(_graph_module, graph_type)
        return _graph_class

    @property
    def figure(self) -> go.Figure:
        graph = self.get_graph(x=self._df.index, y=self._df[self._col], name=self._name, **self._graph_kwargs)
        _figure = go.Figure(data=graph, layout=self._layout)
        # NOTE: Use the default theme from plotly version 3.x, template=None
        _figure["layout"].update(template=None)
        return _figure

class SubplotsGraph:
    def __init__(self, row=3, col=2):
        self.kwargs = dict(
            #shared_xaxes=True,
            vertical_spacing=0.01,
            rows=row,
            cols=col,
            #row_width=[1, 1, 1, 3, 1, 1, 3],
            print_grid=False,
        )
        self._figure = make_subplots(**self.kwargs)

    def add_graph(self,graph_type,df,row,col):
        if graph_type == 'line':
            graph = go.Line

        for col_name in list(df.columns):
            g = graph(x=df.index,y=df[col_name])
            self._figure.append_trace(g, row=row, col=col)



    def show(self):

        N = 100
        random_x = np.linspace(0, 1, N)
        random_y0 = np.random.randn(N) + 5
        random_y1 = np.random.randn(N)
        random_y2 = np.random.randn(N) - 5

        # Create traces
        trace0 = go.Scatter(
            x=random_x,
            y=random_y0,
            mode='lines',
            name='markers'
        )
        self._figure.append_trace(trace0,2, 1)

        data = [
            ["姓名", "年龄", "性别"],
            ["古明地觉", 17, "女"],
            ["古明地恋", 16, "女"],
            ["椎名真白", 18, "女"],
            ["坂上智代", 19, "女"],
            ["雨宫优子", 16, "女"],
        ]
        fig = ff.create_table(data)

        number = np.random.randint(80, 100, 4)
        self._figure.add_trace(
            go.Table(
                header=dict(values=['A Scores', 'B Scores']),  # 设置表头
                cells=dict(values=[number,  # 通过numpy给定数据
                                   [95, 85, 75, 95]])),row = 2, col = 1)

        py.plot(self._figure)

    def show2(self):
        # 给定表格数据
        table_data = [['Team', 'Wins', 'Losses', 'Ties'],  # 直接给定每行的数据
                      ['Montréal<br>Canadiens', 18, 4, 0],  # 数据的换行显示
                      ['Dallas Stars', 18, 5, 0],
                      ['NY Rangers', 16, 5, 0],
                      ['Boston<br>Bruins', 13, 8, 0],
                      ['Chicago<br>Blackhawks', 13, 8, 0],
                      ['LA Kings', 13, 8, 0],
                      ['Ottawa<br>Senators', 12, 5, 0]]
        # Initialize a figure with ff.create_table(table_data)
        fig = ff.create_table(table_data,  # 表格数据
                              height_constant=60)  # 间隔

        # 给定画图的数据
        x = ['Montréal Canadiens', 'Dallas Stars', 'NY Rangers',  # 队名
             'Boston Bruins', 'Chicago Blackhawks', 'LA Kings', 'Ottawa Senators']

        GFPG = [3.54, 3.48, 3.0, 3.27, 2.83, 2.45, 3.18]  # 2种得分
        GAPG = [2.17, 2.57, 2.0, 2.91, 2.57, 2.14, 2.77]
        # Make traces for graph
        fig.add_trace(go.Scatter(x=x, y=GFPG,
                                 marker=dict(color='#0099ff'),  # 指定颜色
                                 name='Goals For<br>Per Game',  # 名称
                                 xaxis='x2', yaxis='y2'))
        fig.add_trace(go.Scatter(x=x, y=GAPG,
                                 marker=dict(color='#404040'),
                                 name='Goals Against<br>Per Game',
                                 xaxis='x2', yaxis='y2'))

        fig.update_layout(
            title_text='Title of Figure',  # 整个figure的名称
            margin={'t': 50, 'b': 100},  # 与顶部和底部的距离
            xaxis={'domain': [0, .5]},  # 表格的x轴范围
            xaxis2={'domain': [0.6, 1]},  # 图形占据的x轴范围
            yaxis2={'anchor': 'x2',  # 表示yaxis的绘图是以x2为基准，title显示在yaxis上
                    'title': 'Goals'}
        )

        fig.show()

if __name__ == '__main__':
    from plotly.subplots import make_subplots

    data = [
        ["姓名", "年龄", "性别"],
        ["古明地觉", 17, "女"],
        ["古明地恋", 16, "女"],
        ["椎名真白", 18, "女"],
        ["坂上智代", 19, "女"],
        ["雨宫优子", 16, "女"],
    ]
    #va = data.sort_values('Order Date')
    fig = make_subplots(
        rows=2, cols=2,
        #shared_xaxes=True,
        vertical_spacing=0.03,
        specs=[[{},{"type": "table"}],
               [{"type": "scatter"},{}]]
    )

    N = 100
    random_x = np.linspace(0, 1, N)
    random_y0 = np.random.randn(N) + 5
    random_y1 = np.random.randn(N)
    random_y2 = np.random.randn(N) - 5

    # Create traces
    trace0 = go.Scatter(
        x=random_x,
        y=random_y0,
        mode='lines',
        name='markers'
    )
    fig.add_trace(trace0, row=1, col=1)
    fig.add_trace(trace0,row=2,col=1)

    fig.add_trace(
        go.Table(
            header=dict(
                values=["姓名", "年龄", "性别"],
                font=dict(size=10),
                align="left"
            ),
            cells=dict(
                values=data[1:3],
                align="left")
        ),
        row=1, col=2
    )
    fig.update_layout(
        height=800,
        showlegend=False,
        title_text="Profits from 2015 to 2018",
        xaxis=dict(title='Year'),
        yaxis=dict(title='Profit'),
    )
    py.plot(fig)
